using MediatR;
using RAG.Domain.Events.User;
using Microsoft.Extensions.Logging;
using RAG.Application.Services.Interfaces;
using RAG.Application.Dtos.SystemLog;
using Microsoft.AspNetCore.Http;

namespace RAG.Application.Events.Handlers;

public class UserEventHandlers : 
    INotificationHandler<UserCreatedEvent>,
    INotificationHandler<UserUpdatedEvent>,
    INotificationHandler<UserDeletedEvent>,
    INotificationHandler<UserRoleAssignedEvent>,
    INotificationHandler<UserStatusChangedEvent>
{
    private readonly ILogger<UserEventHandlers> _logger;
    private readonly ISystemLogService _systemLogService;
    private readonly IHttpContextAccessor _httpContextAccessor;

    public UserEventHandlers(ILogger<UserEventHandlers> logger, ISystemLogService systemLogService, IHttpContextAccessor httpContextAccessor)
    {
        _logger = logger;
        _systemLogService = systemLogService;
        _httpContextAccessor = httpContextAccessor;
    }

    private string GetCurrentOperator()
    {
        try
        {
            var httpContext = _httpContextAccessor.HttpContext;
            if (httpContext?.User?.Identity?.IsAuthenticated == true)
            {
                var userId = httpContext.User.FindFirst("UserId")?.Value;
                var userName = httpContext.User.FindFirst("UserName")?.Value;
                
                if (!string.IsNullOrEmpty(userId) && !string.IsNullOrEmpty(userName))
                {
                    return $"操作者: {userName} (ID: {userId})";
                }
                else if (!string.IsNullOrEmpty(userName))
                {
                    return $"操作者: {userName}";
                }
                else if (!string.IsNullOrEmpty(userId))
                {
                    return $"操作者: 用户ID {userId}";
                }
            }
            
            return "操作者: 系统自动操作";
        }
        catch (Exception ex)
        {
            _logger.LogWarning(ex, "获取当前操作用户信息失败");
            return "操作者: 未知用户";
        }
    }

    public async Task Handle(UserCreatedEvent notification, CancellationToken cancellationToken)
    {
        // 控制台输出
        Console.ForegroundColor = ConsoleColor.Green;
        Console.WriteLine("=== 用户创建事件 ===");
        Console.WriteLine($"用户ID: {notification.UserId}");
        Console.WriteLine($"用户名: {notification.UserName}");
        Console.WriteLine($"邮箱: {notification.Email}");
        Console.WriteLine($"创建时间: {notification.CreatedAt:yyyy-MM-dd HH:mm:ss}");
        Console.WriteLine("==================");
        Console.ResetColor();

        // 日志记录
        _logger.LogInformation("用户创建事件: 用户ID={UserId}, 用户名={UserName}, 邮箱={Email}, 创建时间={CreatedAt}", 
            notification.UserId, notification.UserName, notification.Email, notification.CreatedAt);
        
        // 写入数据库日志
        try
        {
            var systemLogDto = new SystemLogDto
            {
                ActionType = "create", // 用户创建操作
                Action = $"系统创建了新用户 '{notification.UserName}'，邮箱为 '{notification.Email}'，用户ID为 '{notification.UserId}'，创建时间为 {notification.CreatedAt:yyyy-MM-dd HH:mm:ss}",
                Target = GetCurrentOperator(),
                CreatedBy = Guid.Empty, // 系统事件，使用空GUID
                CreatedAt = DateTime.UtcNow
            };
            
            await _systemLogService.CreateSystemLogAsync(systemLogDto);
            _logger.LogInformation("用户创建事件已记录到系统日志");
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "记录用户创建事件到系统日志失败");
        }
        
        // 这里可以添加具体的业务逻辑，比如：
        // - 发送欢迎邮件
        // - 创建用户默认设置
        // - 记录审计日志
        // - 发送通知给管理员
        
        await Task.CompletedTask;
    }

    public async Task Handle(UserUpdatedEvent notification, CancellationToken cancellationToken)
    {
        // 控制台输出
        Console.ForegroundColor = ConsoleColor.Yellow;
        Console.WriteLine("=== 用户更新事件 ===");
        Console.WriteLine($"用户ID: {notification.UserId}");
        Console.WriteLine($"用户名: {notification.UserName}");
        Console.WriteLine($"邮箱: {notification.Email}");
        Console.WriteLine($"更新时间: {notification.UpdatedAt:yyyy-MM-dd HH:mm:ss}");
        
        if (!string.IsNullOrEmpty(notification.PreviousUserName) && notification.PreviousUserName != notification.UserName)
        {
            Console.WriteLine($"用户名变更: {notification.PreviousUserName} -> {notification.UserName}");
        }
        
        if (!string.IsNullOrEmpty(notification.PreviousEmail) && notification.PreviousEmail != notification.Email)
        {
            Console.WriteLine($"邮箱变更: {notification.PreviousEmail} -> {notification.Email}");
        }
        Console.WriteLine("==================");
        Console.ResetColor();

        // 日志记录
        _logger.LogInformation("用户更新事件: 用户ID={UserId}, 用户名={UserName}, 邮箱={Email}, 更新时间={UpdatedAt}", 
            notification.UserId, notification.UserName, notification.Email, notification.UpdatedAt);
        
        if (!string.IsNullOrEmpty(notification.PreviousUserName) && notification.PreviousUserName != notification.UserName)
        {
            _logger.LogInformation("用户名已更改: {PreviousUserName} -> {UserName}", 
                notification.PreviousUserName, notification.UserName);
        }
        
        if (!string.IsNullOrEmpty(notification.PreviousEmail) && notification.PreviousEmail != notification.Email)
        {
            _logger.LogInformation("邮箱已更改: {PreviousEmail} -> {Email}", 
                notification.PreviousEmail, notification.Email);
        }
        
        // 写入数据库日志
        try
        {
            var changes = new List<string>();
            if (!string.IsNullOrEmpty(notification.PreviousUserName) && notification.PreviousUserName != notification.UserName)
            {
                changes.Add($"用户名: {notification.PreviousUserName} -> {notification.UserName}");
            }
            if (!string.IsNullOrEmpty(notification.PreviousEmail) && notification.PreviousEmail != notification.Email)
            {
                changes.Add($"邮箱: {notification.PreviousEmail} -> {notification.Email}");
            }
            
            var changeDescription = changes.Any() ? $"，变更内容包括：{string.Join("，", changes)}" : "，但未检测到具体变更内容";
            
            var systemLogDto = new SystemLogDto
            {
                ActionType = "update", // 用户更新操作
                Action = $"系统更新了用户 '{notification.UserName}' (ID: {notification.UserId}) 的信息，更新时间为 {notification.UpdatedAt:yyyy-MM-dd HH:mm:ss}{changeDescription}",
                Target = GetCurrentOperator(),
                CreatedBy = Guid.Empty,
                CreatedAt = DateTime.UtcNow
            };
            
            await _systemLogService.CreateSystemLogAsync(systemLogDto);
            _logger.LogInformation("用户更新事件已记录到系统日志");
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "记录用户更新事件到系统日志失败");
        }
        
        // 这里可以添加具体的业务逻辑，比如：
        // - 发送邮箱变更确认邮件
        // - 更新相关系统的用户信息
        // - 记录审计日志
        
        await Task.CompletedTask;
    }

    public async Task Handle(UserDeletedEvent notification, CancellationToken cancellationToken)
    {
        // 控制台输出
        Console.ForegroundColor = ConsoleColor.Red;
        Console.WriteLine("=== 用户删除事件 ===");
        Console.WriteLine($"用户ID: {notification.UserId}");
        Console.WriteLine($"用户名: {notification.UserName}");
        Console.WriteLine($"邮箱: {notification.Email}");
        Console.WriteLine($"删除时间: {notification.DeletedAt:yyyy-MM-dd HH:mm:ss}");
        Console.WriteLine("==================");
        Console.ResetColor();

        // 日志记录
        _logger.LogInformation("用户删除事件: 用户ID={UserId}, 用户名={UserName}, 邮箱={Email}, 删除时间={DeletedAt}", 
            notification.UserId, notification.UserName, notification.Email, notification.DeletedAt);
        
        // 写入数据库日志
        try
        {
            var systemLogDto = new SystemLogDto
            {
                ActionType = "delete", // 用户删除操作
                Action = $"系统删除了用户 '{notification.UserName}' (ID: {notification.UserId})，邮箱为 '{notification.Email}'，删除时间为 {notification.DeletedAt:yyyy-MM-dd HH:mm:ss}，该用户的所有相关数据已被清理",
                Target = GetCurrentOperator(),
                CreatedBy = Guid.Empty,
                CreatedAt = DateTime.UtcNow
            };
            
            await _systemLogService.CreateSystemLogAsync(systemLogDto);
            _logger.LogInformation("用户删除事件已记录到系统日志");
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "记录用户删除事件到系统日志失败");
        }
        
        // 这里可以添加具体的业务逻辑，比如：
        // - 清理用户相关数据
        // - 发送删除确认邮件
        // - 记录审计日志
        // - 通知相关系统
        
        await Task.CompletedTask;
    }

    public async Task Handle(UserRoleAssignedEvent notification, CancellationToken cancellationToken)
    {
        // 控制台输出
        Console.ForegroundColor = ConsoleColor.Blue;
        Console.WriteLine("=== 用户角色分配事件 ===");
        Console.WriteLine($"用户ID: {notification.UserId}");
        Console.WriteLine($"用户名: {notification.UserName}");
        Console.WriteLine($"角色IDs: {string.Join(", ", notification.RoleIds)}");
        Console.WriteLine($"角色名称: {string.Join(", ", notification.RoleNames)}");
        Console.WriteLine($"分配时间: {notification.AssignedAt:yyyy-MM-dd HH:mm:ss}");
        Console.WriteLine("======================");
        Console.ResetColor();

        // 日志记录
        _logger.LogInformation("用户角色分配事件: 用户ID={UserId}, 用户名={UserName}, 角色IDs={RoleIds}, 角色名称={RoleNames}, 分配时间={AssignedAt}", 
            notification.UserId, notification.UserName, string.Join(",", notification.RoleIds), 
            string.Join(",", notification.RoleNames), notification.AssignedAt);
        
        // 写入数据库日志
        try
        {
            var systemLogDto = new SystemLogDto
            {
                ActionType = "role_assign", // 角色分配操作
                Action = $"系统为用户 '{notification.UserName}' (ID: {notification.UserId}) 分配了角色，分配的角色包括：{string.Join("、", notification.RoleNames)}，分配时间为 {notification.AssignedAt:yyyy-MM-dd HH:mm:ss}，这将影响用户的权限和访问控制",
                Target = GetCurrentOperator(),
                CreatedBy = Guid.Empty,
                CreatedAt = DateTime.UtcNow
            };
            
            await _systemLogService.CreateSystemLogAsync(systemLogDto);
            _logger.LogInformation("用户角色分配事件已记录到系统日志");
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "记录用户角色分配事件到系统日志失败");
        }
        
        // 这里可以添加具体的业务逻辑，比如：
        // - 更新用户权限缓存
        // - 发送角色变更通知
        // - 记录审计日志
        // - 触发权限重新计算
        
        await Task.CompletedTask;
    }

    public async Task Handle(UserStatusChangedEvent notification, CancellationToken cancellationToken)
    {
        // 控制台输出
        Console.ForegroundColor = ConsoleColor.Magenta;
        Console.WriteLine("=== 用户状态变更事件 ===");
        Console.WriteLine($"用户ID: {notification.UserId}");
        Console.WriteLine($"用户名: {notification.UserName}");
        Console.WriteLine($"状态变更: {notification.OldStatus} -> {notification.NewStatus}");
        Console.WriteLine($"变更时间: {notification.ChangedAt:yyyy-MM-dd HH:mm:ss}");
        
        if (notification.NewStatus == "banned")
        {
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine("⚠️  用户已被禁用，需要处理相关会话和权限");
        }
        else if (notification.NewStatus == "active" && notification.OldStatus == "banned")
        {
            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine("✅ 用户已重新激活");
        }
        Console.WriteLine("======================");
        Console.ResetColor();

        // 日志记录
        _logger.LogInformation("用户状态变更事件: 用户ID={UserId}, 用户名={UserName}, 状态变更={OldStatus} -> {NewStatus}, 变更时间={ChangedAt}", 
            notification.UserId, notification.UserName, notification.OldStatus, notification.NewStatus, notification.ChangedAt);
        
        // 写入数据库日志
        try
        {
            string statusDescription = "";
            if (notification.NewStatus == "banned")
            {
                statusDescription = "，用户已被禁用，系统将限制其访问权限并处理相关会话";
            }
            else if (notification.NewStatus == "active" && notification.OldStatus == "banned")
            {
                statusDescription = "，用户已重新激活，恢复其正常访问权限";
            }
            else
            {
                statusDescription = "，用户状态已更新";
            }
            
            var systemLogDto = new SystemLogDto
            {
                ActionType = "status_change", // 状态变更操作
                Action = $"系统变更了用户 '{notification.UserName}' (ID: {notification.UserId}) 的状态，从 '{notification.OldStatus}' 变更为 '{notification.NewStatus}'，变更时间为 {notification.ChangedAt:yyyy-MM-dd HH:mm:ss}{statusDescription}",
                Target = GetCurrentOperator(),
                CreatedBy = Guid.Empty,
                CreatedAt = DateTime.UtcNow
            };
            
            await _systemLogService.CreateSystemLogAsync(systemLogDto);
            _logger.LogInformation("用户状态变更事件已记录到系统日志");
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "记录用户状态变更事件到系统日志失败");
        }
        
        // 这里可以添加具体的业务逻辑，比如：
        // - 根据状态变更发送不同的通知
        // - 更新用户会话状态
        // - 记录审计日志
        // - 触发相关业务流程
        
        if (notification.NewStatus == "banned")
        {
            _logger.LogWarning("用户 {UserName} 已被禁用，需要处理相关会话和权限", notification.UserName);
        }
        else if (notification.NewStatus == "active" && notification.OldStatus == "banned")
        {
            _logger.LogInformation("用户 {UserName} 已重新激活", notification.UserName);
        }
        
        await Task.CompletedTask;
    }
} 